function maximumTotalDamage(power) {
  // 统计每个伤害值的出现次数，并计算总伤害
  const count = {};
  for (const p of power) {
    count[p] = (count[p] || 0) + 1;
  }
  // 计算每个伤害值的总伤害（值 × 次数）
  const value = {};
  for (const p in count) {
    const num = parseInt(p, 10);
    value[num] = num * count[p];
  }
  // 提取并排序所有不同的伤害值
  const sortedPowers = Object.keys(count)
    .map(Number)
    .sort((a, b) => a - b);
  const n = sortedPowers.length;
  if (n === 0) return 0;

  // 初始化动态规划数组
  const dp = new Array(n);
  dp[0] = value[sortedPowers[0]];

  for (let i = 1; i < n; i++) {
    const currentP = sortedPowers[i];
    // 不选当前值的情况
    dp[i] = dp[i - 1];

    // 选择当前值的情况，需要找到最前面一个与当前值相差大于2的位置
    let j = i - 1;
    while (j >= 0 && currentP - sortedPowers[j] <= 2) {
      j--;
    }

    // 计算选择当前值时的最大伤害
    const selectCurrent = value[currentP] + (j >= 0 ? dp[j] : 0);
    dp[i] = Math.max(dp[i], selectCurrent);
  }

  return dp[n - 1];
}

// 测试用例
const power = [5, 9, 2, 10, 2, 7, 10, 9, 3, 8];
console.log(maximumTotalDamage(power)); // 输出：31
